#pragma once

#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <vector>

namespace  Blobs
{

	enum  Criteria
	{
		BY_WIDTH = 0,
		BY_HEIGHT,
		BY_AREA

	};

		

	class Blob
	{
	private :
		cv::Moments moments;
		
		cv::Point center;
		cv::Rect rect;
		int id;
	public:
				
		Blob(const int id)
		{
			this->id = id;

		}
		Blob(const int id, const cv::Rect&rect)
		{
			this->id = id;
			this->rect = rect;
		}

		int GetId()const
		{
			return id;
		}

		void SetMoments(const cv::Moments& m)
		{
			this->moments =m ;
			
		}

		cv::Point GetCentroid()const
		{
			
//centers[i].x = (int)(M10/M00); 
//centers[i].y = (int)(M01/M00); 
			return cv::Point2f(this->moments.m10/this->moments.m00,this->moments.m01/this->moments.m00);
		}


		void SetRect(const cv::Rect &rect)
		{
			this->rect = rect;
		}
		cv::Rect GetRect()const
		{
			return rect;
		}

		int GetWidth()const
		{
			return rect.width;
		}
		
		int GetHeight()const
		{
			return rect.height;
		}
		int GetArea()const
		{
			return rect.area();
		}
	};


	inline bool operator== (const Blobs::Blob&blob1,const Blobs::Blob  & blob2)
	{
		return (blob1.GetRect() == blob2.GetRect() && blob1.GetId() ==  blob2.GetId() );
	}

	class BlobList
	{
	private:
		//cv::Mat img;
		typedef std::vector<Blob> VectorOfBlobs ;

		VectorOfBlobs blobList;
		cv::Mat regionImage;
		int blobsFound;
	public:
		int FindBlobs (const cv::Mat& mat,unsigned char bkg);
		
		int Exclude(const Blobs::Criteria criteria,int value);
		
		int PaintBlobRects(cv::Mat & img);
		int Split(const Blobs::Criteria criteria,int value1,int value2);


		std::vector<cv::Rect> GetBlobRects( )const;
		//int Merge(const int id0, const int id1);
		int Merge(const Blob blob0, const  Blob blob1);
		
		bool MergeNearest(int maxDistanceX, int maxDistanceY, int maxWidth, int maxHeight);
	};



};